home *** CD-ROM | disk | FTP | other *** search
Text File | 1986-09-06 | 4.8 KB | 192 lines | [TEXT/MACA] |
- /*
- * record.c - move recording/playback for the game of Tablut
- */
-
- #include <quickdraw.h>
- #include <window.h>
- #include <memory.h>
- #include "progerr.h"
- #include "tablut.h"
-
- #define BT_NOBODY 0
- #define BT_SWEDE 1
- #define BT_MUSC 2
- #define BT_KING 3
-
- #define BT_NOWIN 0
- #define BT_WHITEWIN 1
- #define BT_BLACKWIN 2
-
- #define STATEBITS 2 /* bits required to store any BT_ value */
- #define STATEMASK 3 /* mask to extract adjusted STATEBITS */
- #define BITSPERBYTE 8 /* number of bits per byte */
-
- struct moveblock *bdblockp; /* pointer to the current memory chunk */
- char *bdmovep; /* pointer to the current state in that chunk */
-
- /*
- * initmoves() - setup the move-recording structures (called only once).
- */
- initmoves()
- {
- curmove = 0;
- nummoves = 0;
- bdblockp = &firstblock;
- bdblockp->nxtblk = (struct moveblock *) 0;
- bdmovep = &(bdblockp->bytes[0]);
- }
-
- /*
- * seekboard() - seek to the given move number in the game.
- */
- seekboard(n)
- int n; /* the move number to go to */
- {
- int blk; /* the chunk index of the move */
- int idx; /* the move index within that chunk */
- if (n >= nummoves) n = nummoves - 1;
- if (n < 0) n = 0;
- blk = n / BDPERBLK;
- idx = n % BDPERBLK;
- for (bdblockp = &firstblock; blk > 0; --blk) {
- bdblockp = bdblockp->nxtblk;
- }
- bdmovep = &(bdblockp->bytes[BOARDBYTES * idx]);
- curmove = n;
- }
-
- /*
- * readboard() - read the board state from the current position in
- * the record.
- */
- readboard()
- {
- int pidx; /* temp piece-index */
- int kidx, sidx, midx; /* king, swede, and muscovite indices */
- int h,v; /* coords */
- char *curbyte; /* current byte within the move record */
- int bits; /* bits representing a grid's state */
- int bitshift; /* shift required to extract "bits" */
-
- for (pidx = 0; pidx < NUMPIECES; ++pidx) {
- hidepiece(pidx); /* hide 'em so they move instantaneously */
- }
- kidx = THEKING;
- sidx = FIRSTSWEDE;
- midx = FIRSTMUSC;
- curbyte = bdmovep;
- bitshift = 0;
- for (h = -4; h <= 4; ++h) {
- for (v = -4; v <= 4; ++v) {
- bits = ((int)(*curbyte) >> bitshift) & STATEMASK;
- switch (bits) {
- case BT_KING:
- if (kidx <= THEKING) placepiece(kidx++, h, v);
- break;
- case BT_SWEDE:
- if (sidx <= LASTSWEDE) placepiece(sidx++, h, v);
- break;
- case BT_MUSC:
- if (midx <= LASTMUSC) placepiece(midx++, h, v);
- break;
- }
- if ((bitshift += STATEBITS) >= BITSPERBYTE) {
- bitshift = 0;
- ++curbyte;
- }
- }
- }
- while (midx <= LASTMUSC) removepiece(midx++);
- while (sidx <= LASTSWEDE) removepiece(sidx++);
- while (kidx <= THEKING) removepiece(kidx++);
-
- bits = ((int)(*curbyte) >> bitshift) & STATEMASK;
- switch(bits) {
- case BT_WHITEWIN: winner = WHITEWIN; setsetup(1); break;
- case BT_BLACKWIN: winner = BLACKWIN; setsetup(1); break;
- default: winner = NOWIN; break;
- }
- advmove(0); /* advance the record without setting EOF */
- }
-
- /*
- * writeboard() - save the current state of the game.
- */
- writeboard()
- {
- int h,v; /* coords */
- char *curbyte; /* current byte within a move record */
- int bits; /* bits representing a grid's state */
- int bitshift; /* shift required to set "bits" */
- char *malloc();
-
- if (bdmovep >= &(bdblockp->bytes[BOARDBYTES * BDPERBLK])) {
- /* allocate a new chunk of memory for recording */
- if (!(bdblockp->nxtblk =
- (struct moveblock *) malloc(sizeof(struct moveblock)))) {
- progstop(PE_NOMEM);
- bomb();
- }
- bdblockp = bdblockp->nxtblk;
- bdblockp->nxtblk = (struct moveblock *) 0;
- bdmovep = &(bdblockp->bytes[0]);
- }
-
- curbyte = bdmovep;
- bitshift = 0;
- for (h = -4; h <= 4; ++h) {
- for (v = -4; v <= 4; ++v) {
- bits = BT_NOBODY;
- if ((*gridp)[h][v]) {
- switch(classbase((*gridp)[h][v])) {
- case FIRSTSWEDE: bits = BT_SWEDE; break;
- case FIRSTMUSC: bits = BT_MUSC; break;
- case THEKING: bits = BT_KING; break;
- }
- }
- if (bitshift == 0) {
- *curbyte = (char) 0;
- }
- *curbyte |= (char)(bits << bitshift);
- if ((bitshift += STATEBITS) >= BITSPERBYTE) {
- bitshift = 0;
- ++curbyte;
- }
- }
- }
-
- bits = BT_NOWIN;
- switch(winner) {
- case WHITEWIN: bits = BT_WHITEWIN; setsetup(1); break;
- case BLACKWIN: bits = BT_BLACKWIN; setsetup(1); break;
- }
- if (bitshift == 0) {
- *curbyte = (char) 0;
- }
- *curbyte |= (char)(bits << bitshift);
- ischanged = 1;
-
- advmove(1); /* advance, setting EOF */
- }
-
- /*
- * advmove() - advance the record one move, optionally setting EOF
- */
- advmove(seteof)
- int seteof; /* if TRUE, the new state is the end one */
- {
- bdmovep += BOARDBYTES;
- if (bdmovep >= &(bdblockp->bytes[BOARDBYTES * BDPERBLK])) {
- if (bdblockp->nxtblk) {
- bdblockp = bdblockp->nxtblk;
- bdmovep = &(bdblockp->bytes[0]);
- }
- }
- ++curmove;
- if (seteof) {
- nummoves = curmove;
- }
- fixlooker();
- drawstate();
- }
-